﻿namespace Example.Cryptography
{
    using System;
    using System.Security.Cryptography;

    public sealed class Salt
    {
        private byte[] _value;

        public Salt(string salt)
            : this(Convert.FromBase64String(salt))
        {
        }

        public Salt(byte[] salt)
        {
            Value = salt;
        }

        private byte[] Value
        {
            get
            {
                return _value;
            }

            set
            {
                if (null == value)
                {
                    throw new ArgumentNullException("value");
                }

                _value = value;
            }
        }

        public static Salt Fresh()
        {
            return Fresh(10);
        }

        public static Salt Fresh(int size)
        {
            if (size < 1)
            {
                throw new ArgumentOutOfRangeException("size", size, "The salt size must be greater then zero.");
            }

            var bytes = new byte[size];
            using (var random = new RNGCryptoServiceProvider())
            {
                random.GetNonZeroBytes(bytes);
            }

            return new Salt(bytes);
        }

        public byte[] ToBytes()
        {
            return Value;
        }

        public override string ToString()
        {
            return Convert.ToBase64String(Value);
        }
    }
}